package com.atguigu.juc;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

import java.util.concurrent.*;

public class CompletableFutureDemo {
    public void getCustomerInfo(){
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void getScore(){
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void getOrderInfo(){
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    public void findOld(){
        long startTime = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName()+"\t"+"------run over...");
        this.getCustomerInfo();
        this.getScore();
        this.getOrderInfo();
        long endTime = System.currentTimeMillis();
        System.out.println("-------costTime: "+(endTime-startTime)+"毫秒");

    }

    public void findNew()throws ExecutionException, InterruptedException {
        Customer customer = new Customer();
        long startTime = System.currentTimeMillis();
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+"\t"+"------111...");
            this.getCustomerInfo();
            customer.setId(123);
            return "OK";
        });
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
        System.out.println(Thread.currentThread().getName()+"\t"+"------222...");
        this.getScore();
        return "OK";
        });
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
        System.out.println(Thread.currentThread().getName()+"\t"+"------333...");
        this.getOrderInfo();
        return "OK";
        });

        CompletableFuture<Void> alled =CompletableFuture.allOf(future1,future2,future3);
        alled.get();//get抛异常，join不抛异常


        long endTime = System.currentTimeMillis();
        System.out.println("-------costTime: "+(endTime-startTime)+"毫秒");

    }

    public void findNew2()throws ExecutionException,InterruptedException{
        Customer customer = new Customer();

        ExecutorService threadPool1 = Executors.newFixedThreadPool(3);//固定线程数线程池
        ExecutorService threadPool2 = Executors.newSingleThreadExecutor();
        Executors.newCachedThreadPool();

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors()+1,
                Runtime.getRuntime().availableProcessors()*2,
                1L,TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(10));
        long startTime = System.currentTimeMillis();
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+"\t"+"------111...");
            this.getCustomerInfo();
            customer.setId(777);
            return "OK";
        },threadPool);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+"\t"+"------222...");
            this.getOrderInfo();
            return "OK";
        },threadPool);

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(()->{
        System.out.println(Thread.currentThread().getName()+"\t"+"------333...");
        this.getScore();
        return "OK";
        },threadPool);

        CompletableFuture<Void> alled =CompletableFuture.allOf(future1,future2,future3);
        alled.get();



        long endTime = System.currentTimeMillis();
        System.out.println("-------costTime: "+(endTime-startTime)+"毫秒");

    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFutureDemo demo = new CompletableFutureDemo();
//        demo.findOld();
//        demo.findNew();
        demo.findNew2();

    }
}


@AllArgsConstructor
@NoArgsConstructor
@Data
class Customer {
    private int id;
    private String customerName;
    private String mark1;
    private String mark2;
}